1 00:00:00,760 --> 00:00:05,740 Alrighty, in this lecture, we're going to set up the local script that's going to be controlling our 2 00:00:05,740 --> 00:00:06,340 guns. 3 00:00:06,340 --> 00:00:11,350 This local script will listen for when our gun is equipped, and then listen for inputs to shoot or 4 00:00:11,350 --> 00:00:12,370 reload the gun. 5 00:00:12,370 --> 00:00:16,990 Since all of the properties for our guns are stored in a separate module. 6 00:00:16,990 --> 00:00:17,500 Scripts. 7 00:00:17,500 --> 00:00:20,440 This local script should work for all of the guns in our game. 8 00:00:20,440 --> 00:00:24,730 So all we need to do is create one local script and then just copy and paste it into each one of our 9 00:00:24,730 --> 00:00:25,030 guns. 10 00:00:25,030 --> 00:00:26,080 So let's get started. 11 00:00:26,080 --> 00:00:28,480 We can create a local script in any one of our guns. 12 00:00:28,480 --> 00:00:29,350 It doesn't matter. 13 00:00:29,350 --> 00:00:32,200 I'll create it in my assault rifle, a new local script. 14 00:00:33,020 --> 00:00:37,670 And inside of our local script, we're going to go ahead and use the same template that we've been using. 15 00:00:37,670 --> 00:00:43,760 I'm going to get rid of this section and this section, and then we can go ahead and create some variables 16 00:00:43,760 --> 00:00:50,420 to refer to our tool so we can get the gun itself, which will just be equal to script dot parent. 17 00:00:50,720 --> 00:00:55,610 We're also going to need to grab the player as well to grab their mouse object. 18 00:00:55,610 --> 00:01:00,080 So we can go ahead and get the player from the player service. 19 00:01:02,800 --> 00:01:06,910 We're also going to need to grab replicated storage, because there's a remote event in there that we're 20 00:01:06,910 --> 00:01:11,830 going to use to communicate with the server when we have shot, or we need to reload our gun. 21 00:01:11,830 --> 00:01:18,130 And the last but not least, to listen for our user input, we're going to use the context action service. 22 00:01:18,130 --> 00:01:20,590 So we'll grab that as well. 23 00:01:21,720 --> 00:01:23,820 And then we can go ahead and refer to our player. 24 00:01:23,820 --> 00:01:25,620 So players local player. 25 00:01:26,260 --> 00:01:28,630 And then we can also get the mouse of our player. 26 00:01:28,630 --> 00:01:30,340 So that's going to be equal to our player. 27 00:01:30,340 --> 00:01:33,220 And there's the function get mouse. 28 00:01:34,160 --> 00:01:37,310 And then we want to go ahead and update a property inside of our mouse. 29 00:01:37,310 --> 00:01:43,010 It's called a target filter and it states determines an object and its descendants to be ignored when 30 00:01:43,010 --> 00:01:45,980 determining mouse dot hit and mouse dot target. 31 00:01:45,980 --> 00:01:51,500 So mouse dot hit and mouse dot target are two properties inside of the mouse that defines what part 32 00:01:51,500 --> 00:01:55,790 the mouse is hovering over, and the position of the mouse in the workspace. 33 00:01:55,790 --> 00:01:59,240 Now we want to ignore any invisible parts in our game. 34 00:01:59,240 --> 00:02:04,910 So we're going to set the target filter equal to the workspace dot filtering folder. 35 00:02:04,910 --> 00:02:09,680 That's why we called it our filtering folder, because we're setting it as the target filter. 36 00:02:09,680 --> 00:02:14,180 And our filtering folder is just filled with a bunch of miscellaneous invisible parts that we don't 37 00:02:14,180 --> 00:02:20,120 want our mouse to interact with when we're calculating the raycast for our gun. 38 00:02:20,750 --> 00:02:23,990 Last but not least, we also want to grab the properties for our gun as well. 39 00:02:23,990 --> 00:02:24,830 That's very important. 40 00:02:24,830 --> 00:02:27,560 So we'll require a gun dot properties. 41 00:02:28,190 --> 00:02:32,570 Now for our gun we want to listen for when our gun is equipped. 42 00:02:33,140 --> 00:02:36,470 And then we also want to listen for when our gun is unequipped. 43 00:02:37,590 --> 00:02:42,210 Now, when our gun is equipped, one of the first things we want to do is we want to update the icon 44 00:02:42,210 --> 00:02:43,770 of our mouse on the screen. 45 00:02:43,770 --> 00:02:50,070 Specifically, we want to set the icon of our mouse to a hit marker so we can set mouse. 46 00:02:50,740 --> 00:02:56,470 The icon and it says the content ID of the image used as the mouse icon. 47 00:02:56,470 --> 00:03:01,810 And I'm going to go ahead and type out the ID of a mouse icon that I found that would work for a gun 48 00:03:01,810 --> 00:03:02,170 system. 49 00:03:02,170 --> 00:03:09,520 So we're going to type out RB asset ID colon and then slash slash, and then the ID for the icon that 50 00:03:09,520 --> 00:03:10,360 I want to use is 51 00:03:10,360 --> 00:03:16,780 11839767092. 52 00:03:16,780 --> 00:03:21,970 So this is going to replace the icon of our mouse with a crosshair. 53 00:03:22,360 --> 00:03:27,460 And then when our gun is equipped the next thing we want to do is we want to listen for input when the 54 00:03:27,460 --> 00:03:30,100 player shoots the gun and when they want to reload the gun. 55 00:03:30,100 --> 00:03:33,370 So we're going to use our context action service and bind an action. 56 00:03:33,370 --> 00:03:36,280 We can call this action our gun shoot. 57 00:03:36,610 --> 00:03:40,120 And then we also want to bind another action for reloading the gun. 58 00:03:40,120 --> 00:03:41,290 So bind action. 59 00:03:41,290 --> 00:03:43,570 We will call this gun reload. 60 00:03:44,700 --> 00:03:50,730 So the function we're going to pass here is going to be passed an action name, an input state as well 61 00:03:50,730 --> 00:03:52,350 as the input object. 62 00:03:55,850 --> 00:03:57,920 Do we want to create a touch button for this? 63 00:03:57,920 --> 00:03:58,610 For shooting? 64 00:03:58,610 --> 00:04:04,070 We're going to do false because the inputs we're going to be listening to is going to be our enum dot 65 00:04:04,070 --> 00:04:11,000 user input type dot mouse button one, as well as the enum dot user input type dot touch. 66 00:04:11,000 --> 00:04:13,670 So we can also support mobile devices. 67 00:04:15,070 --> 00:04:22,180 And then I'm going to copy this and do the exact same thing for our gun reload, but instead the inputs 68 00:04:22,180 --> 00:04:23,950 we want to go ahead and listen to. 69 00:04:24,690 --> 00:04:32,460 Are going to be the enum dot key code dot r, and then we want to create an on screen button for reloading 70 00:04:32,460 --> 00:04:34,320 the gun for mobile players. 71 00:04:35,110 --> 00:04:40,240 Now, since we're going to be able to support whether or not our gun is automatic or semi-automatic, 72 00:04:40,240 --> 00:04:45,760 we want to keep track of when our player is holding down their mouse button or when they have released 73 00:04:45,760 --> 00:04:46,900 their mouse button. 74 00:04:47,470 --> 00:04:51,790 So I'm going to create another variable, and I'm going to call it mouse button down. 75 00:04:51,790 --> 00:04:54,640 And I'm going to set it to false by default. 76 00:04:54,640 --> 00:05:04,330 But if the input state of our mouse button one or our touch if that is equal to the enum dot user input 77 00:05:04,330 --> 00:05:10,810 state of begin, then that means we're beginning to hold down our mouse button so we can set mouse button 78 00:05:10,810 --> 00:05:13,120 down equal to true. 79 00:05:13,920 --> 00:05:21,810 Otherwise, if the input state is equal to the enum dot user input state dot end, then we want to go 80 00:05:21,810 --> 00:05:25,380 ahead and set mouse button down equal to false. 81 00:05:27,070 --> 00:05:28,990 Now for reloading and shooting our gun. 82 00:05:28,990 --> 00:05:32,350 We can go ahead and create a couple of dedicated functions for that. 83 00:05:32,440 --> 00:05:38,650 We can have a function to shoot our gun, and then we can have a function to reload our gun. 84 00:05:39,780 --> 00:05:44,940 And then when we begin to hold down our mouse button or the player begins to touch the screen, then 85 00:05:44,940 --> 00:05:50,220 we want to shoot our gun and we only want to shoot our gun if we have ammo in our magazine. 86 00:05:50,430 --> 00:05:56,400 So in each one of our guns, we actually have an attribute set on them that tells us how much ammo currently 87 00:05:56,400 --> 00:06:01,650 is in the magazine and how much reserve ammo they have, as well as an extra attribute to define whether 88 00:06:01,650 --> 00:06:03,030 or not it is a spread. 89 00:06:03,030 --> 00:06:05,760 So a shotgun, or if it's just a standard gun. 90 00:06:06,390 --> 00:06:11,970 So what we want to do is we want to check if our gun get attribute ammo and mag. 91 00:06:11,970 --> 00:06:17,220 If that's equal to zero, then we don't want to shoot our gun, and instead we want to be able to play 92 00:06:17,220 --> 00:06:22,590 that click sound to tell the player, hey, you don't have any ammo. 93 00:06:23,260 --> 00:06:29,050 So we can go ahead and create that same kind of function we've created before to create a sound instance, 94 00:06:29,410 --> 00:06:33,460 and we'll get past the parent for that sound instance, as well as the sound properties that we'll be 95 00:06:33,460 --> 00:06:35,680 grabbing from our properties module script. 96 00:06:35,680 --> 00:06:40,270 So we'll create a new sound instance dot new sound. 97 00:06:40,420 --> 00:06:45,490 And then we can go ahead and loop through every single property and value in the sound properties. 98 00:06:46,130 --> 00:06:48,200 And then apply that on our sound. 99 00:06:49,590 --> 00:06:54,990 And then afterward, we can set sound parent equal to the parent and then return the sound. 100 00:06:55,560 --> 00:06:59,490 So that way if we don't have any ammo, we can go ahead and create a new sound. 101 00:06:59,490 --> 00:07:04,650 So we'll create a sound, and the parent for that will be the handle of our gun. 102 00:07:05,160 --> 00:07:09,720 And that sound is going to be the properties dot gun click sound properties. 103 00:07:09,720 --> 00:07:12,900 And then we can play this sound when we don't have any ammo. 104 00:07:13,230 --> 00:07:15,540 We'll wait for this sound to complete. 105 00:07:15,540 --> 00:07:19,710 And then we'll just destroy the sound instance and return. 106 00:07:19,950 --> 00:07:25,680 And I'll go ahead and move this after my if statement, because we don't want to set mouse button down 107 00:07:25,680 --> 00:07:28,710 equal to true when we don't have any ammo in our gun. 108 00:07:29,750 --> 00:07:34,730 Now that we confirm that we have enough ammo and we're holding down our mouse button, the next thing 109 00:07:34,730 --> 00:07:38,300 we can check is whether or not this gun is automatic. 110 00:07:38,300 --> 00:07:43,370 If this gun is automatic, then we want to have a while loop running here that will keep shooting our 111 00:07:43,370 --> 00:07:47,780 gun over and over until we either run out of ammo or we lift up our mouse button. 112 00:07:48,260 --> 00:07:54,650 If our gun isn't automatic, then we can simply just call our shoot function, shoot the gun, and then 113 00:07:54,650 --> 00:08:02,210 we also want to be able to wait for a little bit to prevent the player from shooting the gun again based 114 00:08:02,210 --> 00:08:05,420 on the round permanent property of our gun. 115 00:08:05,960 --> 00:08:12,650 So that means we need to calculate the cooldown or the shot cooldown for our gun. 116 00:08:13,440 --> 00:08:16,410 And that's going to be equal to our properties. 117 00:08:16,710 --> 00:08:17,700 Fire rate. 118 00:08:18,030 --> 00:08:20,970 And then there is 60s in a minute. 119 00:08:20,970 --> 00:08:29,100 So we're going to divide 60 by our fire rate to get the cooldown or the time duration between each shot 120 00:08:29,100 --> 00:08:30,840 based on the fire rate. 121 00:08:31,260 --> 00:08:37,350 So that means we can go down and after we shoot our gun we can go ahead and wait for this shot. 122 00:08:37,350 --> 00:08:38,370 Cooldown. 123 00:08:38,760 --> 00:08:43,920 And that means we're going to have to create another boolean to keep track of when we are shooting our 124 00:08:43,920 --> 00:08:48,330 gun, and we'll check if we're already shooting our gun, and then we'll just return. 125 00:08:48,330 --> 00:08:50,310 That way we don't shoot the gun again. 126 00:08:50,310 --> 00:08:52,110 So I'll create a boolean. 127 00:08:52,110 --> 00:08:53,790 I'll call this shooting. 128 00:08:54,510 --> 00:08:56,310 And I'll set that equal to false. 129 00:08:56,310 --> 00:09:01,620 But then when we're holding down our mouse and we have enough ammo, we're going to set shooting equal 130 00:09:01,620 --> 00:09:02,520 to true. 131 00:09:03,940 --> 00:09:06,610 And that means up here we can check if we're shooting our gun. 132 00:09:06,610 --> 00:09:09,940 So if we're already shooting our gun, then we're just going to return. 133 00:09:11,060 --> 00:09:12,410 And then we shoot our gun. 134 00:09:12,410 --> 00:09:17,360 And then after our yield statement is up, we can go ahead and set shooting back to false to allow the 135 00:09:17,360 --> 00:09:18,680 player to shoot the gun again. 136 00:09:19,370 --> 00:09:23,480 Now, if our gun is automatic, we want to keep shooting our gun while our mouse button is held down 137 00:09:23,480 --> 00:09:25,280 or until we run out of ammo. 138 00:09:25,310 --> 00:09:31,370 So while our mouse button is being held down, what we want to do is we want to keep shooting the gun 139 00:09:31,520 --> 00:09:33,770 and then we want to yield for that shot. 140 00:09:33,770 --> 00:09:36,770 Cool down so we maintain that rate of fire. 141 00:09:37,280 --> 00:09:44,090 And then after every single time we shoot, we want to check if the amount of ammo inside of our magazine. 142 00:09:45,900 --> 00:09:47,970 Is less than or equal to zero. 143 00:09:47,970 --> 00:09:53,700 And if it is, we're going to set mouse button down equal to false and then break out of this loop to 144 00:09:53,700 --> 00:09:55,680 no longer shoot our gun anymore. 145 00:09:56,400 --> 00:09:59,490 So we're going to be updating these attributes on the server. 146 00:09:59,490 --> 00:10:04,380 Which is why inside of our shoot function we're going to have to fire an event to tell the server, 147 00:10:04,380 --> 00:10:11,460 hey, we shot our gun, please subtract ammo from us and please detect what we've hit and apply damage 148 00:10:11,460 --> 00:10:12,480 and stuff like that. 149 00:10:12,990 --> 00:10:19,230 But this is how it should look when we press down our mouse button or we touch the screen, we're going 150 00:10:19,230 --> 00:10:20,400 to shoot. 151 00:10:20,400 --> 00:10:24,900 And while we are holding down our mouse button, if our gun is automatic, we're going to keep shooting 152 00:10:24,900 --> 00:10:28,290 until our mouse button is released or we run out of ammo. 153 00:10:28,860 --> 00:10:34,470 Now, the other useful thing with the shooting variable is we can go ahead and use it within the function 154 00:10:34,470 --> 00:10:41,610 for reloading our gun, because we don't want to reload our gun in the middle of us shooting our gun. 155 00:10:41,640 --> 00:10:49,560 So what we can do inside of the function for our reload is we want to check if the input state is equal 156 00:10:49,560 --> 00:10:53,460 to the enum dot user input state, and we could do the end input state. 157 00:10:53,460 --> 00:11:00,180 So once they release the R button on their keyboard, or they release from clicking on the button that's 158 00:11:00,180 --> 00:11:06,810 on our screen, if they release, then what we want to do is we want to reload our gun, but we only 159 00:11:06,810 --> 00:11:10,020 want to reload our gun when we're not shooting the gun. 160 00:11:10,020 --> 00:11:15,390 So if we're shooting our gun still, then we're just going to return because we can't reload while we're 161 00:11:15,390 --> 00:11:16,110 shooting the gun. 162 00:11:17,660 --> 00:11:22,610 Now, when we unequip our gun, what we need to do is we need to stop shooting our gun. 163 00:11:22,610 --> 00:11:25,790 So we got to set all of those booleans to false. 164 00:11:25,790 --> 00:11:31,370 And then we want to unbind these different actions from our context action service because we're no 165 00:11:31,370 --> 00:11:33,080 longer holding our gun. 166 00:11:33,080 --> 00:11:36,110 So we want to set mouse button down equal to false. 167 00:11:36,110 --> 00:11:38,450 We want to set shooting equal to false. 168 00:11:38,450 --> 00:11:40,280 And then we want to unbind these actions. 169 00:11:40,280 --> 00:11:42,680 So refer to the context action service. 170 00:11:42,680 --> 00:11:45,200 Unbind the action which is our gun shoot. 171 00:11:45,710 --> 00:11:50,000 And then we need to do the exact same thing for our gun reload. 172 00:11:50,120 --> 00:11:54,470 We also want to reset the mouse icon back to the default. 173 00:11:54,470 --> 00:12:00,140 And to do that we can refer to our mouse and set the icon to an empty string, which should set the 174 00:12:00,140 --> 00:12:02,510 mouse icon back to the default. 175 00:12:03,260 --> 00:12:08,390 Now we can go ahead and fill out our shoot and reload functions. 176 00:12:09,190 --> 00:12:14,800 Now inside of our shoot function, what we need to do is we are going to raycast on the client side 177 00:12:14,800 --> 00:12:18,310 and then send that raycast information to the server. 178 00:12:18,520 --> 00:12:24,280 So we need to set up a raycast parameters to fill out certain types of instances in our game. 179 00:12:24,280 --> 00:12:29,140 For example, we want to filter out our own character, and we also want to filter out the filtering 180 00:12:29,140 --> 00:12:30,790 folder in our workspace. 181 00:12:31,520 --> 00:12:35,840 So inside of the variable section I'm going to create a new raycast parameters. 182 00:12:35,840 --> 00:12:38,360 So raycast params dot new. 183 00:12:38,360 --> 00:12:45,230 And I'm going to set the params dot filter type equal to the enum dot raycast filter type dot exclude. 184 00:12:45,810 --> 00:12:52,050 And then when we shoot our gun, we want to set Rams dot filter descendant instances equal to a table 185 00:12:52,050 --> 00:12:57,000 that contains our player's character, as well as the workspace dot filtering folder. 186 00:12:57,780 --> 00:13:02,040 And then we need to calculate the direction for our raycast. 187 00:13:02,040 --> 00:13:04,050 So we'll call this our shot direction. 188 00:13:04,170 --> 00:13:09,750 And that's going to be equal to our mouse's hit which is the keyframe of the mouse's position in 3D 189 00:13:09,750 --> 00:13:10,200 space. 190 00:13:10,200 --> 00:13:15,150 So we're converting wherever our mouse is on the screen to a position in the world. 191 00:13:15,150 --> 00:13:20,400 So we'll get the hit, we'll get that position, and then we want to subtract it by the origin point, 192 00:13:20,400 --> 00:13:23,130 which is going to be our gun dot handle. 193 00:13:23,130 --> 00:13:27,780 And inside of each of the handles of our gun there is an attachment called muzzle. 194 00:13:28,770 --> 00:13:32,670 And we want to get the world, see frame of that muzzle and then get its position. 195 00:13:33,210 --> 00:13:38,760 And then we want to get a normalized vector or basically a vector that has a length of one stud. 196 00:13:38,760 --> 00:13:43,860 So we're going to get the unit a normalized copy of the vector three one that has the same direction 197 00:13:43,860 --> 00:13:45,720 as the original, but a magnitude of one. 198 00:13:45,720 --> 00:13:52,950 This way we can customize how long we want this vector to be, depending on the properties for our gun. 199 00:13:53,550 --> 00:13:58,410 After we get the shot direction, the next thing we need to determine is whether or not this is a shotgun 200 00:13:58,410 --> 00:13:59,640 or a regular gun. 201 00:13:59,640 --> 00:14:03,300 If this is a shotgun, then we want to spread the bullets out randomly. 202 00:14:03,300 --> 00:14:09,150 But if it's a regular gun, then we only want to shoot one bullet in the shot direction that we've calculated. 203 00:14:09,270 --> 00:14:15,990 So if our gun get attribute if the gun type is equal to the standard gun type. 204 00:14:17,130 --> 00:14:19,380 Then what we can go ahead and do is raycast. 205 00:14:19,380 --> 00:14:22,950 So we'll use the workspace and then the raycast function. 206 00:14:22,950 --> 00:14:27,990 The origin is going to be our gun dot handle dot muzzle dot world keyframe. 207 00:14:29,750 --> 00:14:33,260 Our position and then our direction is going to be our shot direction. 208 00:14:33,260 --> 00:14:37,460 And then we want to multiply this by our properties dot max bullet distance. 209 00:14:37,460 --> 00:14:42,920 So we get a ray that is 500 studs long and the direction that we've defined. 210 00:14:43,400 --> 00:14:46,400 And then we can also pass our raycast parameters. 211 00:14:47,170 --> 00:14:50,710 Then we can get a result from this raycast. 212 00:14:50,980 --> 00:14:57,370 So if we have a result then we want to give this information to the server. 213 00:14:57,400 --> 00:15:02,050 Otherwise if we don't have a result then we're just going to fire the event but not give any information 214 00:15:02,050 --> 00:15:03,640 to the server. 215 00:15:04,700 --> 00:15:08,660 So let's go ahead and make a reference to our gun event. 216 00:15:08,660 --> 00:15:13,130 So that's going to be in replicated storage I'll just create a variable I'll call it gun event. 217 00:15:13,130 --> 00:15:17,990 That's equal to replicated storage dot remotes dot gun event. 218 00:15:19,120 --> 00:15:23,500 Now to create a standard of communication between the client and server. 219 00:15:23,500 --> 00:15:29,080 Basically, what actions do we want the server to do when we click our gun or when we reload our gun? 220 00:15:29,080 --> 00:15:34,030 We can create another module script inside of the enums folder and replicated storage. 221 00:15:34,030 --> 00:15:37,390 And this is going to be our gun comms enum. 222 00:15:37,930 --> 00:15:41,830 And then inside of here we can fill in the different actions that we want the server to do. 223 00:15:41,830 --> 00:15:45,160 So I'm just going to copy this enum here. 224 00:15:45,160 --> 00:15:47,890 Close that out and then paste it in here. 225 00:15:47,890 --> 00:15:53,710 But inside of this table I want to have some actions specifically to give to our server. 226 00:15:55,010 --> 00:15:59,270 One of those actions would be, for example, to validate one of our shots. 227 00:15:59,270 --> 00:16:03,950 So when we shoot our gun, we want the server to check if we hit anything and apply any damage and stuff 228 00:16:03,950 --> 00:16:04,490 like that. 229 00:16:04,490 --> 00:16:07,400 So we could give an action of like a validate shot. 230 00:16:09,120 --> 00:16:13,350 And then another action we want the server to validate is our reload. 231 00:16:13,350 --> 00:16:17,460 So when the client reloads their gun we want to tell the server, hey, we're reloading. 232 00:16:17,460 --> 00:16:20,610 Can you please put more ammo inside of my magazine. 233 00:16:20,610 --> 00:16:22,650 So we'll call this validate reload. 234 00:16:24,940 --> 00:16:28,300 Then we can go ahead and get this enum from upgraded storage. 235 00:16:28,300 --> 00:16:34,420 So I'll just call this my gun comms enum and we'll require from replicated storage dot modules, dot 236 00:16:34,420 --> 00:16:36,490 enums, dot gun comms enum. 237 00:16:36,910 --> 00:16:43,360 And then we can go ahead and use those different constants to tell the server what kind of action we 238 00:16:43,360 --> 00:16:45,040 want them to perform. 239 00:16:45,670 --> 00:16:50,230 So when we have a result from our raycast, we're going to use our gun event and fire to the server. 240 00:16:50,230 --> 00:16:51,670 Hey, we shot our gun! 241 00:16:51,670 --> 00:16:58,690 Please validate our shot so we'll do gun comms enum dot two server dot validate shot, and then we want 242 00:16:58,690 --> 00:17:03,940 to pass them a table containing all the information from our raycast. 243 00:17:03,940 --> 00:17:09,400 Now unfortunately the raycast result that is returned from this function, we can't pass it through 244 00:17:09,400 --> 00:17:10,360 a remote event. 245 00:17:10,360 --> 00:17:12,700 The server will receive nil. 246 00:17:12,700 --> 00:17:18,520 So we basically need to create our own custom table that stores all of the different results that we 247 00:17:18,520 --> 00:17:18,820 want. 248 00:17:18,850 --> 00:17:23,140 So I'm going to create a variable called remote compatible results. 249 00:17:24,080 --> 00:17:28,820 And if we don't convert this raycast result into this table, then we're going to run into issues where 250 00:17:28,820 --> 00:17:30,620 the server is not going to receive it. 251 00:17:30,620 --> 00:17:34,280 This is just a limitation of remote events that we're going to have to work through. 252 00:17:34,280 --> 00:17:38,960 But some of the information from this remote event that I'm going to want to give to the server is, 253 00:17:38,960 --> 00:17:41,870 for example, what is the instance that we hit. 254 00:17:41,870 --> 00:17:44,870 So that's going to be equal to my result dot instance. 255 00:17:45,350 --> 00:17:50,120 Another example is we want to get the position of where we hit in the workspace. 256 00:17:50,120 --> 00:17:54,230 So position is going to be equal to my result dot position. 257 00:17:54,850 --> 00:17:59,590 And then we're also going to want to get the normal vector of the face we hit. 258 00:17:59,590 --> 00:18:01,420 So it's called normal. 259 00:18:01,780 --> 00:18:04,240 And it's going to be equal to my result dot normal. 260 00:18:04,240 --> 00:18:07,060 And it says the normal vector of the intersected face. 261 00:18:07,060 --> 00:18:10,210 So we're going to want that for the server as well. 262 00:18:10,950 --> 00:18:13,500 So this is my remote compatible result. 263 00:18:13,500 --> 00:18:17,130 And then inside of this table I'm going to be given to the server. 264 00:18:17,130 --> 00:18:21,930 I can create a key and I'll just call it my raycast result. 265 00:18:21,930 --> 00:18:25,440 And that's going to be equal to my remote compatible result table. 266 00:18:25,470 --> 00:18:32,490 Now another thing I want to give to the server is the position of the instance on the client side, 267 00:18:32,490 --> 00:18:38,220 because there's going to be a small delay between when we fire this remote event and the server retrieves 268 00:18:38,220 --> 00:18:39,150 the information. 269 00:18:39,150 --> 00:18:46,170 So I want to give the server information of where the instance position was on the client side. 270 00:18:46,170 --> 00:18:51,930 And that way the server can check or compare the position of that instance on the server side to the 271 00:18:51,930 --> 00:18:52,980 client side. 272 00:18:53,070 --> 00:18:56,490 So I'll just call this the instance position. 273 00:18:57,370 --> 00:18:59,800 And it's going to be equal to the result that instance. 274 00:18:59,800 --> 00:19:03,160 And we're going to get the position of that instance. 275 00:19:03,750 --> 00:19:08,880 And this is the information we're going to send to the server to validate our shot for later. 276 00:19:08,910 --> 00:19:14,880 Now, if we didn't hit anything at all, then we can just simply use our gun event and fire to the server 277 00:19:14,880 --> 00:19:16,320 to validate our shot. 278 00:19:16,320 --> 00:19:19,350 So gun comms enum dot two server dot validate shot. 279 00:19:19,350 --> 00:19:22,800 But we're not going to pass any more information because we didn't hit anything. 280 00:19:22,800 --> 00:19:29,940 Instead, we just want the server to deduct one bullet from our magazine and stuff like that and play 281 00:19:29,940 --> 00:19:34,260 the gunshot sound and make a muzzle flash, that kind of thing. 282 00:19:34,560 --> 00:19:39,720 But if we did hit a result, then we want the server to verify that result. 283 00:19:40,280 --> 00:19:44,930 And since we haven't set up the server script yet, I'm just going to print this result on the console. 284 00:19:45,530 --> 00:19:49,190 And then the other thing we want to check is if our gun. 285 00:19:49,950 --> 00:19:53,400 Get attribute gun type if it's equal to spread. 286 00:19:53,400 --> 00:19:58,710 So if our gun is a shotgun then what we need to do is something a little bit different. 287 00:19:58,800 --> 00:20:05,580 What we need to do is we need to create a whole bunch of different raycasts in different directions 288 00:20:05,580 --> 00:20:09,090 to replicate the different pellets coming out of our shotgun. 289 00:20:09,600 --> 00:20:13,110 So this means we're going to need a random data type here. 290 00:20:13,110 --> 00:20:14,520 So random dot new. 291 00:20:14,850 --> 00:20:19,260 And then we're going to create a table I'm going to call it all pellets. 292 00:20:19,260 --> 00:20:26,190 And this table is going to store basically the same thing that we are sending to the server right here. 293 00:20:26,190 --> 00:20:30,780 It's going to store the remote compatible result as well as the instance position. 294 00:20:30,780 --> 00:20:33,540 But we're going to do that for every single pellet in our gun. 295 00:20:33,540 --> 00:20:37,890 So you can imagine this as multiple different bullets in our gun stored in one table. 296 00:20:38,100 --> 00:20:41,730 And then we're going to give this table to our server all at once. 297 00:20:41,730 --> 00:20:45,900 And then the server can loop through all those different results and verify each one of them. 298 00:20:46,550 --> 00:20:51,890 So what we want to do is we want to loop a set number of times. 299 00:20:51,890 --> 00:20:54,500 So we're going to start our AI index at one. 300 00:20:54,500 --> 00:20:58,940 And the number of times we need a loop is going to be equal to how many pellets is going to be coming 301 00:20:58,940 --> 00:20:59,480 out of our gun. 302 00:20:59,480 --> 00:21:03,410 So we're going to get the total pellets in our properties. 303 00:21:04,780 --> 00:21:07,630 And again, this is going to be only for shotguns. 304 00:21:07,750 --> 00:21:15,910 And then what we need to do is we need to randomize the direction of this pellet coming out of our shotgun. 305 00:21:15,910 --> 00:21:20,380 So we want the direction to be somewhat similar to the shot direction of where our mouse is. 306 00:21:20,380 --> 00:21:23,350 But we want to add a little bit of an angle difference. 307 00:21:23,350 --> 00:21:26,860 So that way it spreads out like a shotgun would. 308 00:21:26,890 --> 00:21:32,320 So to do that we're going to update our shot direction variable to be equal to. 309 00:21:32,320 --> 00:21:34,570 And this is going to be a little bit complex. 310 00:21:34,570 --> 00:21:39,790 But what we're going to do is we're going to create a new keyframe and we're going to use the lookup 311 00:21:39,790 --> 00:21:40,210 function. 312 00:21:40,210 --> 00:21:44,380 So we're going to get a position and then another position to look at. 313 00:21:44,380 --> 00:21:46,480 So we'll get a keyframe from that. 314 00:21:46,570 --> 00:21:52,090 The starting position is going to be our gun dot handle dot muzzle dot world keyframe. 315 00:21:53,200 --> 00:21:53,920 That position. 316 00:21:53,920 --> 00:21:59,590 So again, the same starting position and where we want to look is going to be equal to our mouse dot 317 00:21:59,590 --> 00:22:01,090 hit dot position. 318 00:22:01,480 --> 00:22:07,870 So this is basically just giving us the exact same vector as calculating it up here. 319 00:22:07,870 --> 00:22:14,170 But instead we want to apply a little bit of a rotation by using a c frame dot angles. 320 00:22:14,800 --> 00:22:20,770 Because after we apply that rotation, we can go ahead and get the look vector of the C frame, which 321 00:22:20,770 --> 00:22:23,980 will be a vector that has a length or magnitude of one stud. 322 00:22:23,980 --> 00:22:27,820 So it's going to be the exact same as this shot direction up here. 323 00:22:27,820 --> 00:22:34,300 But instead we have a little bit of a random rotation to our vector. 324 00:22:34,910 --> 00:22:42,200 So now what we want to do is we want to multiply this new C frame by a C frame angles. 325 00:22:42,710 --> 00:22:44,480 Now let me get the look vector here. 326 00:22:45,130 --> 00:22:50,830 And we want to rotate it randomly on the x and the y axis and not the z axis. 327 00:22:50,830 --> 00:22:56,470 Because if you imagine this as like our 2D screen, we have an X and a y component to our screen, and 328 00:22:56,470 --> 00:23:01,450 we need to rotate the ray randomly on the x and y axis to give that spread effect. 329 00:23:01,450 --> 00:23:05,950 And the amount that we want to randomly rotate it by is defined in our properties. 330 00:23:05,950 --> 00:23:10,870 So if we look at one of the properties for our shotgun, we had that max spread property. 331 00:23:10,870 --> 00:23:17,170 And this is going to be in degrees of how severe the pellet spread is for our shotgun. 332 00:23:18,080 --> 00:23:24,290 So what we need to do is for example, on the x axis we want to use math dot rad. 333 00:23:24,530 --> 00:23:29,030 And then we want to get a random number between negative five and positive five. 334 00:23:29,030 --> 00:23:31,220 So we could do RNG next integer. 335 00:23:32,010 --> 00:23:34,380 Or actually we'll do next number. 336 00:23:35,480 --> 00:23:39,110 And then it's going to be between our properties. 337 00:23:39,290 --> 00:23:39,680 Max. 338 00:23:39,680 --> 00:23:40,400 Spread. 339 00:23:42,320 --> 00:23:45,950 And then we'll have a negative value to a positive value. 340 00:23:46,070 --> 00:23:48,740 So we'll copy that and do that there as well. 341 00:23:48,740 --> 00:23:51,470 And again we want to do this for both the x axis. 342 00:23:51,470 --> 00:23:53,330 So let me copy this. 343 00:23:55,050 --> 00:23:58,350 And then we also want to do it for the y axis. 344 00:23:58,350 --> 00:24:00,450 And then for the z axis we do not care. 345 00:24:00,450 --> 00:24:03,360 We're going to set that value equal to zero. 346 00:24:04,920 --> 00:24:10,830 So now, to make this look a little bit more clear, I'm going to space this out there and space this 347 00:24:10,830 --> 00:24:11,670 out there. 348 00:24:11,670 --> 00:24:19,170 So we're getting a C frame that's looking at wherever our mouse is in the workspace from the muzzle 349 00:24:19,170 --> 00:24:19,920 of our gun. 350 00:24:19,920 --> 00:24:25,200 And then we're applying a slight rotation to that C frame on the x and y axis. 351 00:24:25,800 --> 00:24:29,190 And then once we do all of that, we can go ahead and grab the look vector. 352 00:24:29,860 --> 00:24:35,830 Which will give us a direction with a length or a magnitude of one stud that we can go ahead and then 353 00:24:35,830 --> 00:24:39,490 multiply and by the max bullet distance. 354 00:24:39,820 --> 00:24:45,100 So we're basically just randomizing a direction for each one of the pellets in our gun. 355 00:24:45,280 --> 00:24:51,010 So after we have modified the shot direction then we can go ahead and do the exact same thing that we 356 00:24:51,010 --> 00:24:52,000 did up here. 357 00:24:52,570 --> 00:24:54,190 We'll raycast. 358 00:24:55,100 --> 00:25:01,400 Multiply that shot direction by our bullet distance and then check if we got a result. 359 00:25:02,000 --> 00:25:06,980 Now, if you remember inside of the properties module script for our shotgun, we only want to do this 360 00:25:06,980 --> 00:25:09,500 randomization of the pellets. 361 00:25:09,500 --> 00:25:14,540 If the round type is set to anything other than the slug round type. 362 00:25:14,570 --> 00:25:19,850 So if I look in one of my shotguns, if you remember, we set one of the round types here to slug. 363 00:25:20,090 --> 00:25:25,730 Since this is set to the slug round type, I don't want to randomize. 364 00:25:26,270 --> 00:25:31,580 The pellets coming out of the shotgun, so we only want to randomize it. 365 00:25:31,820 --> 00:25:36,350 If the round type is equal to slug. 366 00:25:36,350 --> 00:25:41,030 So what we want to do in here is we want to check. 367 00:25:41,890 --> 00:25:47,830 If the property's not around type is not equal to slug. 368 00:25:48,490 --> 00:25:55,360 So if it's not equal to the slug round type, then we can go ahead and randomize the direction of our 369 00:25:55,360 --> 00:25:55,990 pellet. 370 00:25:56,700 --> 00:26:02,100 But otherwise we'll just keep the shot direction the same, like we've calculated up here. 371 00:26:02,610 --> 00:26:08,010 And then actually let me move this into our for loop, because we need to do it for each one of the 372 00:26:08,010 --> 00:26:09,360 pellets in our shotgun. 373 00:26:09,570 --> 00:26:14,280 So we'll get the result for the first pellet and then the next pellet and then the next. 374 00:26:14,280 --> 00:26:21,090 And when we grab that result, we want to check if we have a result from our raycast. 375 00:26:21,090 --> 00:26:27,900 And if we do well we can go ahead and do is copy this right here and create another remote compatible 376 00:26:27,900 --> 00:26:28,770 result. 377 00:26:28,770 --> 00:26:34,560 And then instead of firing to the server for every single pellet, because that means we would be firing 378 00:26:34,560 --> 00:26:37,590 our remote event many times instantaneously. 379 00:26:37,710 --> 00:26:41,850 Instead, we're going to insert this result into our all pellets table. 380 00:26:41,850 --> 00:26:48,420 So we'll use Table.insert, refer to all pellets and then we want to insert. 381 00:26:49,050 --> 00:26:52,680 The same type of thing that we passed to the server right here. 382 00:26:52,680 --> 00:26:54,450 So we'll copy this. 383 00:26:55,240 --> 00:27:00,130 And the table or the value we're inserting into all palettes, is that right there? 384 00:27:00,130 --> 00:27:05,440 So we're getting our remote compatible result, as well as the position of the instance that we hit 385 00:27:05,440 --> 00:27:07,240 with this particular pellet. 386 00:27:08,820 --> 00:27:13,050 And then once we're done looping through all of the total pellets in our gun. 387 00:27:13,550 --> 00:27:16,760 Then we can go ahead and fire to the server. 388 00:27:16,760 --> 00:27:20,210 So gun event, fire server. 389 00:27:21,070 --> 00:27:24,130 The gun comms enum o2 server dot validate shot. 390 00:27:24,130 --> 00:27:28,690 And we're just going to pass to the server the entirety of the all pellets table. 391 00:27:29,640 --> 00:27:31,380 And then we'll just print out. 392 00:27:32,020 --> 00:27:35,920 All of the pellets here on the client because again, we haven't set up the server script yet. 393 00:27:36,810 --> 00:27:42,390 Okay, that was a lot of code to write, but we should be able to test what we have down so far and 394 00:27:42,390 --> 00:27:45,780 see if we get any results printed out into the console. 395 00:27:45,780 --> 00:27:51,150 If we hit something with one of our bullets, this should print the raycast result of what we hit. 396 00:27:51,150 --> 00:27:55,740 If we didn't hit anything, then this should print nil inside of our assault rifle. 397 00:27:55,740 --> 00:28:00,420 What we can go ahead and do is we'll just copy our assault rifle and paste that clone inside of our 398 00:28:00,420 --> 00:28:01,350 starter pack. 399 00:28:02,020 --> 00:28:07,690 And then we can go ahead and playtest the game to see if we get any raycast results from trying to shoot 400 00:28:07,690 --> 00:28:08,590 our gun. 401 00:28:09,480 --> 00:28:12,660 So we didn't get any errors in the console, which is always good. 402 00:28:12,720 --> 00:28:14,520 And then here we're holding our gun. 403 00:28:14,520 --> 00:28:17,280 We're going to be adding animations for our guns later. 404 00:28:17,280 --> 00:28:19,980 But right now we need to just set up the basics for our gun. 405 00:28:19,980 --> 00:28:21,630 So if I click my gun. 406 00:28:22,160 --> 00:28:27,530 As you can see, we got a raycast result and it hit a union in our game at this position. 407 00:28:27,530 --> 00:28:33,050 As you can see, we got the normal of the face we hit, and then it also tells us the material that 408 00:28:33,050 --> 00:28:33,980 we hit as well. 409 00:28:34,400 --> 00:28:36,890 So that is our raycast result. 410 00:28:36,890 --> 00:28:39,260 If I shoot maybe this barrier right here. 411 00:28:39,800 --> 00:28:43,370 As you can see, it tells us we hit a concrete barrier at this position. 412 00:28:43,370 --> 00:28:44,420 Very cool. 413 00:28:44,570 --> 00:28:50,300 Maybe if I walk over here and shoot this, um, let me shoot this door over here. 414 00:28:50,300 --> 00:28:52,880 If I shoot that, it says we hit a part. 415 00:28:52,880 --> 00:28:54,410 Maybe if I shoot this. 416 00:28:54,410 --> 00:28:56,870 As you can see, it says we hit a sandbag barrier. 417 00:28:56,870 --> 00:29:00,290 So it looks like our raycast on the client is working fine. 418 00:29:00,290 --> 00:29:03,800 We're hitting the sidewalk or we're hitting this ground part. 419 00:29:04,660 --> 00:29:08,740 Or maybe if we shoot this over here, we're hitting a trash pile. 420 00:29:09,070 --> 00:29:10,960 Again, we're hitting more sandbags. 421 00:29:10,960 --> 00:29:11,620 Very cool. 422 00:29:11,620 --> 00:29:17,320 So it looks like our raycasts are correctly calculating what they are hitting. 423 00:29:18,410 --> 00:29:24,110 So the next thing I want to go ahead and test to see what the output will be for a shotgun. 424 00:29:24,500 --> 00:29:27,320 So I can go ahead and copy this local script. 425 00:29:27,680 --> 00:29:32,360 And then let me just pick out a random shotgun like this one. 426 00:29:32,360 --> 00:29:37,520 I'll just paste that local script inside of there, and then I'll copy this shotgun and then paste it 427 00:29:37,520 --> 00:29:38,360 in my starter pack. 428 00:29:38,360 --> 00:29:40,040 And then we can play test the game again. 429 00:29:41,620 --> 00:29:46,780 We'll go and play the game, and then let's see what the result is going to be for every single pellet 430 00:29:46,780 --> 00:29:48,700 that comes out of our shotgun. 431 00:29:48,700 --> 00:29:51,100 So if I just shoot right here. 432 00:29:51,850 --> 00:29:52,210 There we go. 433 00:29:52,210 --> 00:29:53,710 We got a table printed out. 434 00:29:54,250 --> 00:29:57,010 And this shotgun shoots out 16 different pellets. 435 00:29:57,010 --> 00:30:01,900 So as you can see, we got the result for each one of the pellets that came out of our shotgun. 436 00:30:04,090 --> 00:30:04,390 Here. 437 00:30:04,390 --> 00:30:08,800 It tells us the position of the instance that we hit, and it tells us that we hit a part. 438 00:30:09,010 --> 00:30:10,930 This one also hit a part. 439 00:30:10,960 --> 00:30:13,030 Let's go ahead and look through all the different. 440 00:30:13,060 --> 00:30:15,730 This one hit a part so it looks like they all just hit the part. 441 00:30:15,760 --> 00:30:20,770 Let me shoot them at one of my barriers and actually let me back up a little bit. 442 00:30:20,770 --> 00:30:24,340 So one of the pellets could have the chance to hit something in the background. 443 00:30:24,340 --> 00:30:25,510 So if I shoot. 444 00:30:26,720 --> 00:30:27,290 There we go. 445 00:30:27,290 --> 00:30:31,220 We got another result and let's go ahead and see what they hit. 446 00:30:31,220 --> 00:30:32,750 This one hit a part. 447 00:30:33,380 --> 00:30:35,210 That one also hit a part. 448 00:30:35,210 --> 00:30:36,890 That one hit a part. 449 00:30:37,010 --> 00:30:39,380 That one hit a part part. 450 00:30:39,380 --> 00:30:42,260 Let me see if any hit the concrete barrier. 451 00:30:42,710 --> 00:30:44,150 That one hit a part. 452 00:30:45,270 --> 00:30:48,240 So far, it looks like none of them hit the concrete barrier. 453 00:30:55,200 --> 00:30:57,720 So looks like they're all still hitting some kind of part. 454 00:30:57,750 --> 00:31:04,140 Maybe if I walk closer and I shoot my concrete barrier like that, maybe we'll get a different result. 455 00:31:05,220 --> 00:31:05,880 There we go. 456 00:31:05,880 --> 00:31:10,980 Since we hit the concrete barrier, if I back up and maybe have like half the pellets hit the barrier, 457 00:31:10,980 --> 00:31:11,940 so I shoot. 458 00:31:13,360 --> 00:31:14,620 There, I got a different result. 459 00:31:14,620 --> 00:31:16,480 Let's see what the result for that is. 460 00:31:17,080 --> 00:31:19,450 Okay, some of them hit the concrete barrier. 461 00:31:19,450 --> 00:31:20,950 Hopefully some of them didn't. 462 00:31:20,950 --> 00:31:23,320 So let's see if any hit a different part. 463 00:31:23,970 --> 00:31:25,170 Concrete barrier. 464 00:31:25,200 --> 00:31:26,310 Concrete barrier. 465 00:31:26,340 --> 00:31:27,540 Concrete barrier. 466 00:31:29,170 --> 00:31:36,610 Actually, it looks like the pellets are all hitting at the exact same position and they are not spreading 467 00:31:36,610 --> 00:31:37,780 out correctly. 468 00:31:37,780 --> 00:31:44,050 If you take a look at the different positions of where these pellets are hitting, they're all hitting 469 00:31:44,050 --> 00:31:45,310 at the same position. 470 00:31:45,310 --> 00:31:51,610 So it appears that the randomization of the direction of our pellets is not working correctly. 471 00:31:51,610 --> 00:31:54,880 So we need to go ahead and troubleshoot why that is. 472 00:31:56,210 --> 00:31:56,570 All right. 473 00:31:56,570 --> 00:32:03,050 And the reason why the pellets were not randomizing or spreading out randomly is because we made a minor 474 00:32:03,050 --> 00:32:08,990 mistake with our next number function call, and that's because we forgot to remove this negative symbol 475 00:32:08,990 --> 00:32:11,870 for the x and then for the y position. 476 00:32:11,870 --> 00:32:18,620 So it was picking the exact same number because it was constrained between the exact two same numbers. 477 00:32:18,620 --> 00:32:23,750 So now that we got rid of those negative symbols, our pellets should be spreading out randomly. 478 00:32:23,750 --> 00:32:30,770 So let me go ahead and copy this script and then update that and paste it inside of our semi-auto shotgun. 479 00:32:30,950 --> 00:32:35,300 And let's go ahead to test to see if the pellets are now spreading out randomly. 480 00:32:35,820 --> 00:32:41,940 So if I go and I shoot, let me put my crosshair halfway between my barrier. 481 00:32:42,240 --> 00:32:46,410 About half of my pellets should have hit the barrier, and then the other half should have hit other 482 00:32:46,410 --> 00:32:49,050 stuff behind in that direction. 483 00:32:49,050 --> 00:32:51,330 So let's go ahead and take a look at the results. 484 00:32:52,840 --> 00:32:54,040 So as you can see, there we go. 485 00:32:54,040 --> 00:32:57,130 One of them hit my sidewalk, which was in the background. 486 00:32:57,340 --> 00:32:59,710 Another one hit my concrete barrier. 487 00:33:00,010 --> 00:33:03,940 And as you can see, the position of where they're hitting these elements are different. 488 00:33:03,970 --> 00:33:06,610 This one also hit the concrete barrier. 489 00:33:06,790 --> 00:33:08,890 This result hit the barrier. 490 00:33:08,920 --> 00:33:09,700 What did this one hit? 491 00:33:09,730 --> 00:33:12,490 This one hit a block somewhere at a different position. 492 00:33:13,960 --> 00:33:17,050 This one hits the barrier as well. 493 00:33:17,080 --> 00:33:19,210 This one hit another block. 494 00:33:19,900 --> 00:33:21,670 This one hit the barrier. 495 00:33:22,310 --> 00:33:24,080 That one also hit the sidewalk. 496 00:33:24,080 --> 00:33:29,120 So as you can see, all of the pellets randomly spread out and hit different things. 497 00:33:29,120 --> 00:33:32,390 That was either the barrier or stuff behind the barrier. 498 00:33:32,420 --> 00:33:33,260 Very cool. 499 00:33:35,060 --> 00:33:39,980 The last thing we can go ahead and fill out for this lecture is going to be the reload function. 500 00:33:39,980 --> 00:33:46,580 So when we want to reload the gun first we want to verify that the amount of bullets in our magazine 501 00:33:46,580 --> 00:33:52,910 is less than the max bullets that we can hold in our magazine, which signifies we need to reload. 502 00:33:52,910 --> 00:33:59,750 So if our gun and we get the attribute ammo and magazine if that is equal to our properties dot max 503 00:33:59,750 --> 00:34:03,230 mag ammo, then the player doesn't need to reload. 504 00:34:03,230 --> 00:34:07,880 Or if the player doesn't have any reserve ammo left, then they can't reload either. 505 00:34:07,880 --> 00:34:16,550 So if gun get attributes ammo reserve if that is equal to zero, then we're just going to return because 506 00:34:16,550 --> 00:34:18,500 the player can't reload their gun. 507 00:34:18,500 --> 00:34:26,660 We also need to create a Debounce for our reload function and we'll create another variable. 508 00:34:26,660 --> 00:34:29,870 I'll call this reloading set that equal to false. 509 00:34:29,870 --> 00:34:34,640 And that way while we are reloading our gun, we also can't shoot our gun. 510 00:34:34,640 --> 00:34:38,330 So what we want to do in here is we want to set reloading equal to true. 511 00:34:38,600 --> 00:34:42,320 And then if we are already reloading our gun we don't need to reload it again. 512 00:34:42,320 --> 00:34:43,700 So we'll return there. 513 00:34:43,820 --> 00:34:48,530 And then if we want to shoot our gun, what we want to check here is if we are shooting, we're going 514 00:34:48,530 --> 00:34:49,190 to return. 515 00:34:49,190 --> 00:34:53,870 And if we are reloading, then we also want to return. 516 00:34:54,960 --> 00:35:00,930 And then what we can do is after we set reloading equal to true, we can go ahead and play the reloading 517 00:35:00,930 --> 00:35:01,380 sound. 518 00:35:01,380 --> 00:35:03,090 So we'll create another new sound. 519 00:35:03,090 --> 00:35:05,190 And that's going to be create sound. 520 00:35:05,190 --> 00:35:11,160 We'll pass gun dot handle and then we'll pass properties dot reload sound properties. 521 00:35:12,030 --> 00:35:15,180 We'll play that sound, and then we'll wait for that sound to end. 522 00:35:15,210 --> 00:35:16,680 So we'll connect a function to that. 523 00:35:16,680 --> 00:35:19,140 And then we're going to go ahead and destroy that sound. 524 00:35:20,060 --> 00:35:23,150 And then here is where we would play like our reload animation. 525 00:35:23,150 --> 00:35:28,310 But since we don't have a reload animation at the moment as a placeholder, I'm just going to put a 526 00:35:28,310 --> 00:35:32,240 yield statement here and we're going to wait for the properties dot reload duration. 527 00:35:32,720 --> 00:35:40,820 And then afterwards we want to go ahead and fire to the server to reload our guns. 528 00:35:40,820 --> 00:35:45,680 So gun coms enum dot two server dot validate reload. 529 00:35:45,740 --> 00:35:49,760 Now we only want to reload our gun if we still have it equipped. 530 00:35:49,760 --> 00:35:55,760 So if let's say the player reloads their gun, but then they unequip their gun in the middle of reloading 531 00:35:55,760 --> 00:35:55,880 it. 532 00:35:55,880 --> 00:35:58,730 We don't want to tell the server to reload our gun. 533 00:35:59,060 --> 00:36:07,670 So what we can do is when we unequip our gun, we can also set reloading equal to false and then back 534 00:36:07,670 --> 00:36:13,100 inside of our reload function we can check if we are reloading. 535 00:36:13,100 --> 00:36:20,900 So if reloading is still true then we can go ahead and fire to the server to reload our gun. 536 00:36:21,470 --> 00:36:29,660 And then once that is all done, we can go ahead and set reloading equal to false. 537 00:36:30,740 --> 00:36:38,330 So now to test this out, we can just basically print that we're reloading. 538 00:36:39,610 --> 00:36:44,920 And then we can go ahead and copy this local script and paste it into our two guns. 539 00:36:45,100 --> 00:36:48,220 And then we can go ahead and get rid of the previous local scripts. 540 00:36:48,220 --> 00:36:51,070 And then I'm going to set the ammo my guns to zero. 541 00:36:51,070 --> 00:36:54,910 So that way we can actually test out to see if they're going to reload. 542 00:36:54,910 --> 00:36:59,560 Of course the attributes aren't going to update, but at least we can still hear the reloading sound 543 00:36:59,560 --> 00:37:01,390 as well as the gun clicks sound. 544 00:37:01,900 --> 00:37:07,930 So since neither of my guns have ammo in the magazines, if I click, as you can see, it's pulling 545 00:37:07,930 --> 00:37:09,730 that click sound that we're out of ammo. 546 00:37:09,730 --> 00:37:11,950 And the same thing should happen with our shotgun. 547 00:37:11,950 --> 00:37:17,380 So if I click, as you can see, we can't shoot because we have no ammo. 548 00:37:18,040 --> 00:37:21,280 Now if I hit R there we go. 549 00:37:21,310 --> 00:37:23,260 The reload sound is playing. 550 00:37:23,960 --> 00:37:26,960 And as you can see inside of the console it has printed reloading. 551 00:37:26,960 --> 00:37:27,710 Perfect. 552 00:37:27,710 --> 00:37:29,870 We can do the same thing for the AR. 553 00:37:29,900 --> 00:37:34,340 If I press R we're reloading the gun and then it should print reloading. 554 00:37:34,340 --> 00:37:34,730 There we go. 555 00:37:34,730 --> 00:37:35,240 Perfect. 556 00:37:35,240 --> 00:37:36,170 Reloading. 557 00:37:37,000 --> 00:37:40,210 So now we have all the client functionality set up for our guns. 558 00:37:40,240 --> 00:37:46,810 The next thing we need to do is start scripting and filling out all the functionality for verifying 559 00:37:46,810 --> 00:37:51,580 and validating when our gun shoots and when our gun reloads. 560 00:37:51,580 --> 00:37:58,150 And then the server can handle all of that kind of stuff, like checking and applying damage, updating 561 00:37:58,150 --> 00:38:03,820 the attributes in our gun, playing the muzzle flash and the gun shoot, sound effects and all that 562 00:38:03,820 --> 00:38:04,960 kind of good stuff. 563 00:38:05,630 --> 00:38:10,430 If you're ready to do all of that, then I will see you in the next lecture.